<?php

// +----------------------------------------------------------------------
// | GaoYu 签名处理类
// +----------------------------------------------------------------------
// | Author: join
// +----------------------------------------------------------------------
// | Date: 2016-03-10
// +----------------------------------------------------------------------
namespace Tyrone\Lib\Extend;

class Sign
{
    public static $newSign;
    public static $signStr;

    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para
     * @return bool|string
     */
    public static function createLinkString($para)
    {
        $arg = http_build_query($para);
        //如果存在转义字符，那么去掉转义
        if (get_magic_quotes_gpc()){
            $arg = stripslashes($arg);
        }
        $arg = str_replace(array("+","%2A","%7E","%28","%29","%21"),array("%20","*","~","(",")","!"),$arg);
        return $arg;
    }

    /**
     * 除去数组中的空值和签名以及ip地址参数
     * @param $para
     * @return mixed
     */
    public static function paraFilter($para)
    {
        unset($para['sign']);
        return $para;
    }

    /**
     * 对数组排序
     * @param $para
     * @return mixed
     */
    public static function argSort($para)
    {
        ksort($para);
        reset($para);
        return $para;
    }

    /**
     * 签名字符串
     * @param $preStr
     * @param $key
     * @return string
     */
    public static function md5Sign($preStr, $key)
    {
        self::$signStr = $preStr;
        self::$newSign = md5($preStr.$key);
        return self::$newSign;
    }

    /**
     * 验证签名
     * @param $params
     * @param $sign
     * @param $key
     * @return bool
     */
    public static function validateSign($params,$sign,$key)
    {
        //根据入参与key生成新的签名
        $newSign = Sign::buildMD5sign($params,$key);
        //签名验证不返回
        if($newSign === $sign)
            return true;
        return false;
    }

    /**
     * 根据传入的数组以及密钥进行md5签名
     * @param $params
     * @param $key
     * @return string
     */
    public static function buildMD5sign($params,$key)
    {
        //除去数组中的空值和签名参数
        $newParams = Sign::paraFilter($params);
        //排序数组
        $sortParam = Sign::argSort($newParams);
        //拼接字符串,按照“参数=参数值”的模式用“&”字符拼接成字符串
        $preStr = Sign::createLinkString($sortParam);
        //进行md5签名并返回
        return Sign::md5Sign($preStr,$key);
    }

    /**
     * 将传入的数组进行解码
     * @param $params
     * @return array
     */
    public static function deCodeParams($params)
    {
        $newParams = array();
        while(list ($key, $val) = each($params)){
            $newParams[$key] = urldecode($params[$key]);
        }
        return $newParams;
    }

}
?>